<template>
  <div class="base-form">
    <n-form ref="elBaseForm" :model="model" :rules="rules" v-bind="$attrs">
      <template v-for="v in forms">
        <n-form-item
          :class="[v.Required === 3 ? 'required-item' : '']"
          :path="`${v.FormKey}.Value`"
          :label="v.FormLabel"
          :required="v.Required === 3"
        >
          <!-- 单选 -->
          <div v-if="v.Formtype === 1">
            <n-radio-group v-model:value="model[v.FormKey].Value">
              <n-radio
                v-for="r in v.options"
                :key="r.Id"
                :label="r.OpeionValue"
                :value="r.OptionKey"
              ></n-radio>
            </n-radio-group>
          </div>

          <!-- 多选 -->
          <div v-else-if="v.Formtype === 2">
            <n-checkbox-group v-model:value="model[v.FormKey].Value">
              <n-checkbox
                v-for="r in v.options"
                :key="r.Id"
                :label="r.OpeionValue"
                :value="r.OptionKey"
              ></n-checkbox>
            </n-checkbox-group>
          </div>

          <!-- 单行文本、多行文本 -->
          <div v-else-if="[3, 5].includes(v.Formtype)">
            <n-input
              clearable
              :type="v.Formtype === 3 ? 'text' : 'textarea'"
              v-model:value="model[v.FormKey].Value"
            ></n-input>
          </div>

          <!-- 评分 -->
          <div v-else-if="v.Formtype === 4">
            <n-rate
              :count="v.MaxLength"
              :allow-half="v.FormDesc == 1"
              v-model:value="model[v.FormKey].Value"
            ></n-rate>
          </div>

          <!-- 单张照片、多张照片 -->
          <div v-else-if="[6, 7].includes(v.Formtype)">
            <BaseUpload
              multiple
              accept=".jpeg, .jpg"
              list-type="image-card"
              :max="v.MaxLength"
              v-model:value="model[v.FormKey].Value"
            ></BaseUpload>
          </div>

          <!-- 年月日、年月日时分秒 -->
          <div v-else-if="[8, 9].includes(v.Formtype)">
            <n-date-picker
              clearable
              format="yyyy/MM/dd HH:mm:ss"
              :type="v.Formtype === 8 ? 'date' : 'datetime'"
              v-model:formatted-value="model[v.FormKey].Value"
            ></n-date-picker>
          </div>

          <!-- 单选选择器、多选选择器 -->
          <div v-else-if="[12, 13].includes(v.Formtype)">
            <n-select
              clearable
              label-field="OpeionValue"
              value-field="OptionKey"
              :multiple="v.Formtype === 12 ? false : true"
              :options="v.options"
              v-model:value="model[v.FormKey].Value"
            ></n-select>
          </div>
        </n-form-item>
      </template>
    </n-form>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'

const elBaseForm = ref(null)
const props = defineProps(['baseForms'])

// 数据源
const forms = ref([])

// 表单
const model = ref({})
const rules = ref({})

watch(
  () => props.baseForms,
  () => {
    initForm()
  },
  {
    immediate: true,
  }
)

// 初始化表单
function initForm() {
  forms.value = formatBaseForms(props.baseForms)
  model.value = {}
  rules.value = {}

  for (const v of forms.value) {
    model.value[v.FormKey] = {
      Value: null,
      SheetFormId: null,
    }
    rules.value[v.FormKey] = {
      Value: {
        message: `请填写${v.FormLabel}`,
        required: v.Required === 3,
      },
    }
  }
}

// 回显表单
function reviewForm(data = {}) {
  for (const rKey of Object.keys(data)) {
    const { Value, SheetFormId } = data[rKey]

    for (const key of Object.keys(model.value)) {
      if (rKey === key) {
        model.value[key] = {
          Value,
          SheetFormId,
        }
      }
    }
  }
}

// 验证表单
function validateForm() {
  return new Promise((resolve, reject) => {
    elBaseForm.value?.validate((errs) => {
      if (errs) {
        reject(errs)
      } else {
        resolve(model.value)
      }
    })
  })
}

// 格式化数据
function formatBaseForms(baseForms = []) {
  baseForms.forEach((b) => {
    // Key
    b.FormKey = b.FormLabel
  })

  return baseForms
}

defineExpose({
  model,
  reviewForm,
  validateForm,
})
</script>

<style lang="scss" scoped>
:deep(.n-input),
:deep(.n-select) {
  width: 400px;
}

:deep(.n-form) {
  .n-form-item {
    &.required-item {
      .n-form-item-label {
        position: relative;
        padding-left: 12px;

        .n-form-item-label__asterisk {
          position: absolute;
          left: 0;
          top: 0;
          color: red;
        }
      }
    }
  }
}
</style>
